#include "music.h"
#include "gd32e23x_it.h"
#include "config.h"
#include "sub_device.h"
#include "led_display.h"

//#define MUSIC_SDA_PORT            GPIOB
//#define MUSIC_SDA_PIN             GPIO_PIN_2
#define MUSIC_SDA_PORT            GPIOB
#define MUSIC_SDA_PIN             GPIO_PIN_1

#define MUSIC_CLK_PORT            GPIOB        //not used
#define MUSIC_CLK_PIN             GPIO_PIN_1



#define MUSIC_CLK_LEVEL_SET       gpio_bit_set(MUSIC_CLK_PORT, MUSIC_CLK_PIN)
#define MUSIC_CLK_LEVEL_RESET       gpio_bit_reset(MUSIC_CLK_PORT, MUSIC_CLK_PIN)
#define MUSIC_SDA_LEVEL_SET       gpio_bit_set(MUSIC_SDA_PORT, MUSIC_SDA_PIN)
#define MUSIC_SDA_LEVEL_RESET       gpio_bit_reset(MUSIC_SDA_PORT, MUSIC_SDA_PIN)

#define MUSIC_TIMER_ENABLE       timer_enable(TIMER2)
#define MUSIC_TIMER_DISABLE       timer_disable(TIMER2)

static volatile uint16_t music_delay_cnt;
void TIMER2_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_UP)){
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER2, TIMER_INT_UP);
        if(music_delay_cnt!=0)
        music_delay_cnt--;
    }
}

static music_delay_100us(uint16_t n)
{
   music_delay_cnt = n;
   while(music_delay_cnt);
}


static void music_send_one_byte(uint8_t dat)
{
   #if 0
   
   MUSIC_TIMER_ENABLE;
   MUSIC_CLK_LEVEL_RESET;
   MUSIC_SDA_LEVEL_SET;
   music_delay_100us(40);//>=4ms
   for(uint8_t i=0; i<8; i++)
   {
      if(dat&0x1)
        MUSIC_SDA_LEVEL_SET;
      else
        MUSIC_SDA_LEVEL_RESET;
        dat>>=1;
        MUSIC_CLK_LEVEL_SET;
      //MUSIC_CLK_LEVEL_RESET;
      music_delay_100us(3);   //delay 500us at least
      //MUSIC_CLK_LEVEL_SET;
      MUSIC_CLK_LEVEL_RESET;
      music_delay_100us(3);   //delay 500us at least
      
   }
   MUSIC_TIMER_DISABLE;
   //MUSIC_CLK_LEVEL_RESET;
   MUSIC_SDA_LEVEL_SET;
   MUSIC_CLK_LEVEL_SET;
   #else
   /*MUSIC_TIMER_ENABLE;
   MUSIC_SDA_LEVEL_RESET;
   music_delay_100us(25);
   for(uint8_t i=0; i<8; i++)
   {
      MUSIC_SDA_LEVEL_SET;
      if(dat&0x1)
      {
         music_delay_100us(24);
         MUSIC_SDA_LEVEL_RESET;
         music_delay_100us(8);
      }
      else
      {
         music_delay_100us(8);
         MUSIC_SDA_LEVEL_RESET;
         music_delay_100us(24);
      }
      dat>>=1;
   }
   MUSIC_SDA_LEVEL_SET;
   MUSIC_TIMER_DISABLE;*/

   MUSIC_TIMER_ENABLE;
   MUSIC_SDA_LEVEL_SET;
   music_delay_100us(80);
   MUSIC_SDA_LEVEL_RESET;
   music_delay_100us(10);
   for(uint8_t i=0; i<8; i++)
   {
      if((dat>>(7-i))&0x1)
      {
         MUSIC_SDA_LEVEL_SET;
         music_delay_100us(15);
         MUSIC_SDA_LEVEL_RESET;
         music_delay_100us(5);
      }
      else
      {
         MUSIC_SDA_LEVEL_SET;
         music_delay_100us(5);
         MUSIC_SDA_LEVEL_RESET;
         music_delay_100us(15);
      }
   }
   MUSIC_TIMER_DISABLE;
   #endif
}

void music_set_vol(uint8_t vol, uint8_t flag)
{
 
   uint8_t tmp;
   if(vol>3)
     vol=0;
   
   switch(vol)
   {
      case 0:
           tmp = 0xeb;
      break;
      case 1:
           tmp = 3;
      break;
      case 2:
           tmp = 10;
      break;
      case 3:
           tmp = 14;
      break;
   }
   
   if(vol==0)
   music_send_one_byte(0xeb);
   else
   {
      music_send_one_byte(0xf1+tmp);
      
   }
   if(flag==0)
   return;
   
   delay_1ms(5);
   music_play_item(gateway.play_music);
   
   set_blue_display_mode(VOL_CHANGE_MODE);
   
   gateway.u.flash.vol=vol;
   record_gateway_in_flash();
}

void music_stop_play(void)
{
   music_send_one_byte(0xFE);
}

void music_cycle_play(void)
{
   music_send_one_byte(0xFE);
}

void music_play_item(uint8_t item)
{
   
   music_send_one_byte(item);
   
}

void music_init(void)
{
   rcu_periph_clock_enable(RCU_GPIOA);
   rcu_periph_clock_enable(RCU_GPIOB);
   gpio_mode_set(MUSIC_SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, MUSIC_SDA_PIN);
   gpio_output_options_set(MUSIC_SDA_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, MUSIC_SDA_PIN);

   gpio_mode_set(MUSIC_CLK_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, MUSIC_CLK_PIN);
   gpio_output_options_set(MUSIC_CLK_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, MUSIC_CLK_PIN);

   gpio_mode_set(MUSIC_BUSY_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, MUSIC_BUSY_PIN);
   MUSIC_SDA_LEVEL_RESET;
   //MUSIC_CLK_LEVEL_SET;
   timer_parameter_struct timer_initpara;

   rcu_periph_clock_enable(RCU_TIMER2);
   timer_deinit(TIMER2);
   /* TIMER2 configuration */
    timer_initpara.prescaler         = 71;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 100;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER2,&timer_initpara);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER2);
    timer_interrupt_enable(TIMER2, TIMER_INT_UP);
    nvic_irq_enable(TIMER2_IRQn, 3);
    delay_1ms(200);
    music_set_vol(gateway.u.flash.vol, 0);

    //delay_1ms(100);
    #if 0
    uint8_t cnt=0,vol=0;
    uint8_t dat=15;
    while(1)
    {
       if(MUSIC_BUSY_LEVEL_GET())
       {
          /*printf("current vol = %d\r\n",vol);
          music_set_vol(vol++);
          
          if(vol==8)vol=0;
          delay_1ms(100);
          music_send_one_byte(cnt);*/
          //music_play_item(14);
         // music_send_bytes(&dat,1);
         music_send_one_byte(16);
          printf("----------\r\n");
        //  delay_1ms(1000);
       }
      
    }
    #endif
}


